XcodeのDevelopment Assetsを使ってSwiftUIプレビューを実装する

XcodeのDevelopment Assetsを使ってSwiftUIプレビューを実装する

Clock Icon2024.07.05

SwiftUIを使ってiOSアプリを開発する際に、デザインの確認のためにプレビュー機能を使用している。本記事では、Xcodeの機能である「Development Assets」を使って、プレビュー専用データをSwiftUIプレビューに表示する方法を紹介する。

Development Assetsとは

Development Assetsは、Xcodeの機能の一つである。デバッグ実行時やプレビューなど、開発中のみに必要な(リリース時には不要な)リソースやソースコードを管理して、アプリをアーカイブする際にはそれらを除外する。この機能によって、プレビューなどの開発用リソースと本番リソースの分離ができ、リリースビルドには不要なファイルが含まないようにできる。

Development Assetsの設定方法

いつから追加された機能であるかは記憶にないが、最近のXcodeでは新規にプロジェクトを作成するとDevelopment Assetsが設定済みである。既存のアプリに対してDevelopment Assetsを追加したい場合には以下の手順をおこなう。

  1. Preview Contentグループを作成する。
  2. プロジェクトナビゲータでターゲットを選択する。
  3. Generalタブを開く。
  4. 最下部にスクロールして、Development Assetsの項目を探す。
  5. 設定フィールドに {プロジェクト名}/Preview Content とグループを選択する
  6. 指定したディレクトリに、プレビュー時に必要なリソースやソースコードを配置する。

Preview Contentグループには、開発中に使用するリソースを配置しておこう。後述しているが、プレビュー専用のデータを扱う PreviewItems ファイルを Preview Content に追加している。

20240704224310

Development Assetsを使って効率よくSwiftUIプレビューを実装する

次に、SwiftUIのプレビュー専用のデータを管理する方法を見ていこう。あまり実用的ではないが説明用に Item というクラスを用意する。アプリ上では name を表示させるということにしておく (説明は後述)。

struct Item {
    let name: String
}

プレビュー専用のデータを作成する

Preview Contentフォルダ内にプレビュー専用のアイテムを定義するファイルを作成した。ここでは、プレビュー用に PreviewItemsというenumを使用して、staticなプロパティとしてプレビュー用のアイテムを定義している。

import Foundation

enum PreviewItems {
    static let previewItem1 = Item(
        name: "プレビュー用のアイテム"
    )

余談だが、列挙子がないのに enum を使っていると驚く方がいるかもしれない。staticなプロパティのホストとしてenumを利用することは、Swiftで名前空間を作成する標準的な手法である。空の列挙型はインスタンス化できないため enum を使う。

Itemを表示する画面と、そのプレビューコードを実装する

最後に通常のプロダクションコードで使用するSwiftUIのビューを定義する。前述した Item を表示するだけの簡単な画面だ。#Previewセクションで、PreviewItems.previewItem1を使ってContentViewのプレビューを設定している。

import SwiftUI

struct ContentView: View {
    let item: Item

    var body: some View {
        VStack {
            Text(item.name)
        }
        .padding()
    }
}

#Preview {
    ContentView(
        item: PreviewItems.previewItem1
    )
}

プレビューを表示すると、下図のようにpreviewItem1 として定義したデータが表示される。

20240704224330

Preview Content に json ファイルを入れてプレビュー表示させる

また、プレビュー用のデータをJSONファイルで扱いたいケースもあるだろう。このセクションでは、Preview ContentにJSONファイルを入れてプレビューで表示させる方法を紹介する。

まず、JSONファイルをデシリアライズして利用できるように、Decodable を適合させる。

struct Item: Decodable {
    let name: String
}

次に、preview_item.jsonというファイルをPreview Contentグループの配下に配置する。内容は以下の通り。

{
    "name": "jsonから読み込んだファイルだよ"
}

先ほど定義したPreviewItemspreviewItem2を追加する。内部的には preview_item.json を読み出して、JSONデータをデシリアライズしている。

enum PreviewItems {
    static var previewItem2: Item {
        loadJSON(fileName:"preview_item")
    }

    static func loadJSON(fileName: String) -> Item {
        guard let url = Bundle.main.url(forResource: fileName, withExtension: "json") else {
            fatalError("JSON file not found in Development Assets.")
        }

        do {
            let data = try Data(contentsOf: url)
            let decoder = JSONDecoder()
            let item = try decoder.decode(Item.self, from: data)
            return item
        } catch {
            fatalError("Failed to load or parse JSON: \(error)")
        }
    }
}

ContentViewのプレビューに使っていた itemPreviewItems.previewItem2 を利用するように変更し、プレビューを表示すると下図のように表示される。

20240704224313

まとめ

Development Assetsを使ってSwiftUIのプレビューを表示する方法を紹介した。Development Assetsを使ってプレビュー専用のデータを管理する利点はいくつかある。

  • プレビュー用データを専用のファイルに分離することで、コードの可読性と管理のしやすさが向上
  • #Previewセクションで定義されたプレビューを使って、リアルタイムにデザインやレイアウトの確認ができる
  • Preview Contentグループ内のデータは本番ビルドには含まれないため、リリース時のコードに影響を与えない

テスト用データとプロダクションコードが分離できることも嬉しいが、個人的にはアプリをアーカイブすると当該のファイルが除外されて、リリースビルドに含まれない点が一番好きだ。

関連記事

Share this article

facebook logohatena logotwitter logo

© Classmethod, Inc. All rights reserved.